package com.lhkj.ct.meta.modules.gauge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhkj.ct.base.constants.Constants;
import com.lhkj.ct.base.enums.DeleteStatus;
import com.lhkj.ct.base.enums.GlobalStatus;
import com.lhkj.ct.base.model.Option;
import com.lhkj.ct.base.model.dto.PageQuery;
import com.lhkj.ct.base.mybatis.extension.service.impl.BatchHandleServiceImpl;
import com.lhkj.ct.base.utils.LambdaUtils;
import com.lhkj.ct.base.utils.ShiroUtil;
import com.lhkj.ct.base.utils.Validate;
import com.lhkj.ct.meta.modules.gauge.mapper.ScaleMapper;
import com.lhkj.ct.meta.modules.gauge.model.entity.TblScale;
import com.lhkj.ct.meta.modules.gauge.model.entity.TblScaleItemRelation;
import com.lhkj.ct.meta.modules.gauge.model.entity.TblScalePatModule;
import com.lhkj.ct.meta.modules.gauge.model.vo.ScalePageVo;
import com.lhkj.ct.meta.modules.gauge.service.ScaleConfigService;
import com.lhkj.ct.meta.modules.gauge.service.ScaleItemRelationService;
import com.lhkj.ct.meta.modules.gauge.service.ScalePatModuleService;
import com.lhkj.ct.meta.modules.recycle.common.constant.RecycleType;
import com.lhkj.ct.meta.modules.recycle.entity.TblRecycleBin;
import com.lhkj.ct.meta.modules.recycle.service.RecycleBinService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2023-10-08
 */
@Service
public class ScaleConfigServiceImpl extends BatchHandleServiceImpl<ScaleMapper, TblScale> implements ScaleConfigService {

    @Resource
    private RecycleBinService recycleBinService;

    @Resource
    private ScaleItemRelationService scaleItemRelationService;

    @Resource
    private ScalePatModuleService scalePatModuleService;

    /**
     * 量表配置分页列表
     *
     * @param pageQuery 分页查询对象
     */
    @Override
    public IPage<ScalePageVo> selectScalePage(TblScale tblScale, PageQuery pageQuery) {
        Page<TblScale> page = generatePage(pageQuery, OrderItem.asc(LambdaUtils.getUnderLineName(TblScale::getSort, "t")));
        return getBaseMapper().selectScalePage(page, tblScale, pageQuery);
    }

    @Override
    public IPage<TblScale> selectServicePage(TblScale tblScale, PageQuery pageQuery) {
        LambdaQueryWrapper<TblScale> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(TblScale::getId, TblScale::getDisplayName,TblScale::getAmount, TblScale::getIntroduction, TblScale::getScalePicture);
        queryWrapper.eq(TblScale::getRecommend, true);
        queryWrapper.eq(TblScale::getStatus, GlobalStatus.NORMAL);
        queryWrapper.eq(TblScale::getDelFlag, DeleteStatus.NORMAL);
        Page<TblScale> page = generatePage(pageQuery, OrderItem.asc(LambdaUtils.getUnderLineName(TblScale::getSort)));
        return getBaseMapper().selectPage(page, queryWrapper);
    }

    @Override
    public IPage<Option<String>> selectScaleOptions(PageQuery pageQuery) {
        return getBaseMapper().selectScaleOptions(generatePage(pageQuery), pageQuery);
    }

    @Override
    public List<Map<String, List<Map<String, Object>>>> groupByCategory(TblScale tblScale) {
        return getBaseMapper().groupByCategory(tblScale);
    }

    @Override
    public TblScale getForm(String id) {
        TblScale scale = getBaseMapper().getForm(id);
        Validate.notNull(scale, "测验量表不存在或已删除");
        scale.setPatMouldIds(scalePatModuleService.selectByScaleId(scale.getId()));
        scale.setItemIds(scaleItemRelationService.selectByScaleId(scale.getId()));
        return scale;
    }

    @Override
    @Transactional
    public int insert(TblScale entity) {
        int res = getBaseMapper().insert(entity);
        if (res > 0) {
            if (CollectionUtils.isNotEmpty(entity.getItemIds())) {
                Set<TblScaleItemRelation> relations = entity.getItemIds()
                        .stream()
                        .map(s -> new TblScaleItemRelation(s, entity.getId()))
                        .collect(Collectors.toSet());
                scaleItemRelationService.saveBatch(relations);
            }
            if (CollectionUtils.isNotEmpty(entity.getPatMouldIds())) {
                Set<TblScalePatModule> modules = entity.getPatMouldIds()
                        .stream()
                        .map(s -> new TblScalePatModule(entity.getId(), s))
                        .collect(Collectors.toSet());
                scalePatModuleService.saveBatch(modules);
            }
        }
        return res;
    }

    @Override
    public int updateById(TblScale entity) {
        int res = getBaseMapper().updateById(entity);
        if (res > 0) {
            scaleItemRelationService.deleteByScaleId(entity.getId());
            if (CollectionUtils.isNotEmpty(entity.getItemIds())) {
                Set<TblScaleItemRelation> relations = entity.getItemIds()
                        .stream()
                        .map(s -> new TblScaleItemRelation(s, entity.getId()))
                        .collect(Collectors.toSet());
                scaleItemRelationService.saveBatch(relations);
            }
            scalePatModuleService.remove(new LambdaQueryWrapper<TblScalePatModule>().eq(TblScalePatModule::getScaleId, entity.getId()));
            if (CollectionUtils.isNotEmpty(entity.getPatMouldIds())) {
                Set<TblScalePatModule> modules = entity.getPatMouldIds()
                        .stream()
                        .map(s -> new TblScalePatModule(entity.getId(), s))
                        .collect(Collectors.toSet());
                scalePatModuleService.saveBatch(modules);
            }
        }
        return res;
    }

    @Override
    public boolean checkGaugeNameUnique(TblScale scale) {
        return getBaseMapper().checkGaugeNameUnique(scale) == 0;
    }

    @Override
    public int removeByIds(Collection<? extends Serializable> idList) {
        return recycleBinService.logicDelete((List<String>) idList, this::logicDelete);
    }

    @Override
    @Transactional
    public int logicDelete(String id) {
        TblScale target = getBaseMapper().selectById(id);
        if (null == target) return 0;
        return recycleBinService.logicDeleteRealSource(
                getBaseMapper(),
                id,
                TblScale::getId,
                TblScale::getDelFlag,
                DeleteStatus.DELETED,
                TblRecycleBin.builder().sourceId(id).title(target.getScaleName()).sourceType(RecycleType.SCALE).build());
    }

    @Override
    public String qrCode(String scaleId) {
        TblScale scale = getBaseMapper().selectById(scaleId);
        Validate.validState(scale != null && scale.getDelFlag() != DeleteStatus.DELETED && scale.getStatus() != GlobalStatus.DISABLED, "量表不存在或已停用！");
        UriComponentsBuilder redirectBuilder = UriComponentsBuilder.fromUriString(Constants.SERVICE_BASE_URL).path("/ct/api/plat/psychology/allot/scanAllot");
        redirectBuilder.queryParam("scaleId", scaleId);
        redirectBuilder.queryParam("doctorId", ShiroUtil.getAuthUserInfo().getUserId());
        redirectBuilder.queryParam("deptId", ShiroUtil.getAuthUserInfo().getDeptId());
        return redirectBuilder.toUriString();
    }
}
